<?xml version="1.0" encoding="ISO-8859-1"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
  <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
  <title>imagecl.cpp Example File (mandelbrot/imagecl.cpp)</title>
  <link rel="stylesheet" type="text/css" href="style/style.css" />
  <script src="scripts/jquery.js" type="text/javascript"></script>
  <script src="scripts/functions.js" type="text/javascript"></script>
  <script src="./scripts/superfish.js" type="text/javascript"></script>
  <link rel="stylesheet" type="text/css" href="style/superfish.css" />  <script src="./scripts/narrow.js" type="text/javascript"></script>
  <link rel="stylesheet" type="text/css" href="style/narrow.css" />
  <!--[if IE]>
<meta name="MSSmartTagsPreventParsing" content="true">
<meta http-equiv="imagetoolbar" content="no">
<![endif]-->
<!--[if lt IE 7]>
<link rel="stylesheet" type="text/css" href="style/style_ie6.css">
<![endif]-->
<!--[if IE 7]>
<link rel="stylesheet" type="text/css" href="style/style_ie7.css">
<![endif]-->
<!--[if IE 8]>
<link rel="stylesheet" type="text/css" href="style/style_ie8.css">
<![endif]-->
</head>
<body class="" onload="CheckEmptyAndLoadList();">
<table border="0" cellpadding="0" cellspacing="0" width="100%">
<tr>
<td align="left" valign="top" width="150"><img src="images/qt-logo.png" align="left" border="0" />&nbsp;&nbsp;<img src="images/qtopencl-logo.png" border="0" /></td>
<td width="1">&nbsp;&nbsp;</td><td class="postheader" valign="center"> <a href="index.html"><font color="#004faf">Home</font></a>&nbsp;&middot; <a href="qtopencl-all-classes.html"><font color="#004faf">All Classes</font></a></td>
</table><h1 class="title">imagecl.cpp Example File</h1>
<span class="small-subtitle">mandelbrot/imagecl.cpp</span>
<!-- $$$mandelbrot/imagecl.cpp-description -->
<div class="descr"> <a name="details"></a>
<pre class="highlightedCode brush: cpp"><span class="comment">    /****************************************************************************
    **
    ** Copyright (C) 2010 Nokia Corporation and/or its subsidiary(-ies).
    ** All rights reserved.
    ** Contact: Nokia Corporation (qt-info@nokia.com)
    **
    ** This file is part of the QtOpenCL module of the Qt Toolkit.
    **
    ** $QT_BEGIN_LICENSE:LGPL$
    ** No Commercial Usage
    ** This file contains pre-release code and may not be distributed.
    ** You may use this file in accordance with the terms and conditions
    ** contained in the Technology Preview License Agreement accompanying
    ** this package.
    **
    ** GNU Lesser General Public License Usage
    ** Alternatively, this file may be used under the terms of the GNU Lesser
    ** General Public License version 2.1 as published by the Free Software
    ** Foundation and appearing in the file LICENSE.LGPL included in the
    ** packaging of this file.  Please review the following information to
    ** ensure the GNU Lesser General Public License version 2.1 requirements
    ** will be met: http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
    **
    ** In addition, as a special exception, Nokia gives you certain additional
    ** rights.  These rights are described in the Nokia Qt LGPL Exception
    ** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
    **
    ** If you have questions regarding the use of this file, please contact
    ** Nokia at qt-info@nokia.com.
    **
    **
    **
    **
    **
    **
    **
    **
    ** $QT_END_LICENSE$
    **
    ****************************************************************************/</span>

    #include &quot;imagecl.h&quot;
    #include &quot;palette.h&quot;
    #include &lt;QtCore/qvarlengtharray.h&gt;
    #include &lt;QtGui/qcolor.h&gt;

    class ImageCLContext
    {
    public:
        ImageCLContext() : context(0), glContext(0) {}
        ~ImageCLContext();

        void init(bool useGL, int wid, int ht);

        QCLContext *context;
        QCLContextGL *glContext;
        QCLProgram program;
        QCLKernel mandelbrot;
    };

    void ImageCLContext::init(bool useGL, int wid, int ht)
    {
        if (context) {
            mandelbrot.setGlobalWorkSize(wid, ht);
            return;
        }

        if (useGL) {
            glContext = new QCLContextGL();
            context = glContext;
            if (!glContext-&gt;create())
                return;
        } else {
            context = new QCLContext();
            if (!context-&gt;create())
                return;
        }

        program = context-&gt;buildProgramFromSourceFile
            (QLatin1String(&quot;:/mandelbrot.cl&quot;));
        mandelbrot = program.createKernel(&quot;mandelbrot&quot;);
        mandelbrot.setGlobalWorkSize(wid, ht);
        mandelbrot.setLocalWorkSize(mandelbrot.bestLocalWorkSizeImage2D());
    }

    ImageCLContext::~ImageCLContext()
    {
        delete context;
    }

    Q_GLOBAL_STATIC(ImageCLContext, image_context)

    ImageCL::ImageCL(int width, int height)
        : Image(width, height)
        , img(width, height, QImage::Format_RGB32)
        , lastIterations(-1)
        , initialized(false)
    {
    }

    ImageCL::~ImageCL()
    {
    }

    void ImageCL::init(bool useGL)
    {
        if (initialized)
            return;
        initialized = true;

        <span class="comment">// Initialize the context for GL or non-GL.</span>
        ImageCLContext *ctx = image_context();
        ctx-&gt;init(useGL, wid, ht);
    }

    GLuint ImageCL::textureId()
    {
        init(true);

        ImageCLContext *ctx = image_context();
        if (!textureBuffer.create(ctx-&gt;glContext, wid, ht))
            qWarning(&quot;Could not create the OpenCL texture to render into.&quot;);

        return textureBuffer.textureId();
    }

    void ImageCL::initialize()
    {
        init(false);
    }

    static bool openclDisabled = false;

    bool ImageCL::hasOpenCL()
    {
        if (openclDisabled)
            return false;
        return !QCLDevice::devices(QCLDevice::Default).isEmpty();
    }

    void ImageCL::disableCL()
    {
        openclDisabled = true;
    }

    void ImageCL::generate(int maxIterations, const Palette &amp;palette)
    {
        QRectF region = rgn;

        init();

        ImageCLContext *ctx = image_context();
        QCLKernel mandelbrot = ctx-&gt;mandelbrot;

        <span class="comment">// Upload the color table into a buffer in the device.</span>
        if (colorBuffer.isNull() || lastIterations != maxIterations) {
            QVector&lt;QRgb&gt; colors = palette.createTable(maxIterations);
            if (lastIterations != maxIterations)
                colorBuffer = QCLBuffer();
            if (colorBuffer.isNull()) {
                colorBuffer = ctx-&gt;context-&gt;createBufferDevice
                    (maxIterations * sizeof(float) * 4, QCLMemoryObject::ReadOnly);
            }
            QVarLengthArray&lt;float&gt; floatColors;
            for (int index = 0; index &lt; maxIterations; ++index) {
                QColor color(colors[index]);
                floatColors.append(float(color.redF()));
                floatColors.append(float(color.greenF()));
                floatColors.append(float(color.blueF()));
                floatColors.append(float(color.alphaF()));
            }
            colorBuffer.write(floatColors.constData(),
                              maxIterations * sizeof(float) * 4);
            lastIterations = maxIterations;
        }

        if (!textureBuffer.textureId()) {
            <span class="comment">// Create a buffer for the image in the OpenCL device.</span>
            if (imageBuffer.isNull()) {
                imageBuffer = ctx-&gt;context-&gt;createImage2DDevice
                    (QImage::Format_RGB32, QSize(wid, ht), QCLMemoryObject::WriteOnly);
            }

            <span class="comment">// Execute the &quot;mandelbrot&quot; kernel.</span>
            mandelbrot(imageBuffer, float(region.x()), float(region.y()),
                       float(region.width()), float(region.height()),
                       wid, ht, maxIterations, colorBuffer);
        } else {
            <span class="comment">// Finish previous GL operations on the texture.</span>
            if (ctx-&gt;glContext-&gt;supportsObjectSharing())
                glFinish();

            <span class="comment">// Acquire the GL texture object.</span>
            textureBuffer.acquire();

            <span class="comment">// Execute the &quot;mandelbrot&quot; kernel.</span>
            mandelbrot(textureBuffer, float(region.x()), float(region.y()),
                       float(region.width()), float(region.height()),
                       wid, ht, maxIterations, colorBuffer);

            <span class="comment">// Release the GL texture object and wait for it complete.</span>
            <span class="comment">// After the release is complete, the texture can be used by GL.</span>
            textureBuffer.release();
        }
    }

    void ImageCL::paint(QPainter *painter, const QPoint&amp; point)
    {
        imageBuffer.drawImage(painter, point);
    }</pre>
</div>
<!-- @@@mandelbrot/imagecl.cpp -->
<p /><address><hr /><div align="center">
<table width="100%" cellspacing="0" border="0"><tr class="address">
<td align="left">Copyright &copy; 2010 Nokia Corporation</td>
<td align="right">QtOpenCL Documentation</td>
</tr></table></div></address>  <script src="scripts/functions.js" type="text/javascript"></script>
  <script type="text/javascript">
  var _gaq = _gaq || [];
  _gaq.push(['_setAccount', 'UA-4457116-5']);
  _gaq.push(['_trackPageview']);
  (function() {
  var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
  ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www') + '.google-analytics.com/ga.js';
  var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
  })();
  </script>
</body>
</html>
